#include <cssysdef.h>
#include <QDir>
#include "ctagame.h"
#include "cs.h"


CS_IMPLEMENT_APPLICATION

ctaGame::ctaGame()
{
}

bool ctaGame::Setup()
{
  // Now get the pointer to various modules we need. We fetch them
  // from the object registry. The RequestPlugins() call we did earlier
  // registered all loaded plugins with the object registry.
  // The virtual clock.
  g3d = csQueryRegistry<iGraphics3D> (GetObjectRegistry());
  if (!g3d) return ReportError("Failed to locate 3D renderer!");

  engine = csQueryRegistry<iEngine> (GetObjectRegistry());
  if (!engine) return ReportError("Failed to locate 3D engine!");

  vc = csQueryRegistry<iVirtualClock> (GetObjectRegistry());
  if (!vc) return ReportError("Failed to locate Virtual Clock!");

  kbd = csQueryRegistry<iKeyboardDriver> (GetObjectRegistry());
  if (!kbd) return ReportError("Failed to locate Keyboard Driver!");

  loader = csQueryRegistry<iLoader> (GetObjectRegistry());
  if (!loader) return ReportError("Failed to locate Loader!");

  plugin_mgr = csQueryRegistry<iPluginManager>(GetObjectRegistry());

  model_ldr = csLoadPlugin<iModelLoader> (plugin_mgr, "crystalspace.mesh.loader.factory.sprite.3d.md2");

  cdsys = csQueryRegistry<iCollideSystem> (GetObjectRegistry());
  if (!cdsys) return ReportError ("Failed to locate CD system!");

  fs = csQueryRegistry<iVFS> (GetObjectRegistry());

  reporter = csQueryRegistry<iReporter> (GetObjectRegistry());
  if (!reporter) return ReportError("Failed to locate reporter plugin!");

  // Sound Renderer
  //sndrenderer = csQueryRegistry<iSndSysRenderer> (GetObjectRegistry());
  //if (!sndrenderer) ReportError("Failed to locate Sound renderer!");

  LoadConfig();
  return true;
}

void ctaGame::ProcessFrame ()
{

  // Tell 3D driver we're going to display 3D things.
  if (!g3d->BeginDraw (engine->GetBeginDrawFlags () | CSDRAW_3DGRAPHICS))
    return;

  //cta.Run();
  //if (cta.getCta_state() == eExit)
  //{
    // The user pressed escape to exit the application.
    // The proper way to quit a Crystal Space application
    // is by broadcasting a csevQuit event. That will cause the
    // main runloop to stop. To do that we get the event queue from
    // the object registry and then post the event.
    csRef<iEventQueue> q =
                  csQueryRegistry<iEventQueue> (GetObjectRegistry());
    if (q.IsValid()) q->GetEventOutlet()->Broadcast(csevQuit(GetObjectRegistry()));
  //}
}

void ctaGame::FinishFrame ()
{

        g3d->FinishDraw ();
        g3d->Print (0);

}

bool ctaGame::OnKeyboard(iEvent& ev)
{

  return false;
}

bool ctaGame::OnInitialize(int /*argc*/, char* /*argv*/ [])
{
  // RequestPlugins() will load all plugins we specify. In addition
  // it will also check if there are plugins that need to be loaded
  // from the config system (both the application config and CS or
  // global configs). In addition it also supports specifying plugins
  // on the commandline.

          // Load application-specific configuration file.
    if (!csInitializer::SetupConfigManager(GetObjectRegistry (),
              QDir::tempPath().append("/cta.cfg").toAscii()))
            return ReportError("Failed to initialize configuration manager!");
  iObjectRegistry *object_reg;
  if (!csInitializer::RequestPlugins(object_reg = GetObjectRegistry(),
    CS_REQUEST_VFS,
    CS_REQUEST_OPENGL3D,
    CS_REQUEST_ENGINE,
    CS_REQUEST_FONTSERVER,
    CS_REQUEST_IMAGELOADER,
    CS_REQUEST_LEVELLOADER,
    CS_REQUEST_REPORTER,
    CS_REQUEST_REPORTERLISTENER,
    CS_REQUEST_PLUGIN("crystalspace.collisiondetection.opcode",
                iCollideSystem),
        CS_REQUEST_PLUGIN("crystalspace.console.output.standard",
                iConsoleOutput),
//	CS_REQUEST_PLUGIN("crystalspace.mesh.loader.factory.genmesh.md2",
//		iModelLoader),
                // TODO: Sound not working
        //CS_REQUEST_PLUGIN("crystalspace.sndsys.renderer.software",
        //	iSndSysRenderer),
        //CS_REQUEST_PLUGIN("cel.physicallayer",
        //	iCelPlLayer),
        //CS_REQUEST_PLUGIN("cel.behaviourlayer.test:iCelBlLayer.Test",
        //	iCelBlLayer),
//	CS_REQUEST_PLUGIN("cel.persistance.classic",
//		iCelPersistance),

    CS_REQUEST_END))
    return ReportError("Failed to initialize plugins!");

  LoadConfig();

  csBaseEventHandler::Initialize(GetObjectRegistry());

  // Now we need to setup an event handler for our application.
  // Crystal Space is fully event-driven. Everything (except for this
  // initialization) happens in an event.
  if (!RegisterQueue(GetObjectRegistry(), csevAllEvents(GetObjectRegistry())))
    return ReportError("Failed to set up event handler!");

  return true;
}

void ctaGame::OnExit()
{
}

bool ctaGame::Application()
{
        // Open the main system. This will open all the previously loaded plug-ins.
        // i.e. all windows will be opened.
        if (!OpenApplication (GetObjectRegistry()))
                return ReportError ("Error opening system!");


        // --pl = CS_QUERY_REGISTRY (object_reg, iCelPlLayer);
        // --bltest = CS_QUERY_REGISTRY_TAG_INTERFACE(object_reg, "iCelBlLayer.Test", iCelBlLayer);
        // Setup
        if (!Setup())
                return false;

  // This calls the default runloop. This will basically just keep
  // broadcasting process events to keep the game going.
        Run ();

        return true;
}

bool ctaGame::LoadConfig()
{
        return true;
}
